package com.qwt.part_time_api.handler;


import com.alibaba.fastjson.JSON;
import com.qwt.part_time_api.error.ErrorCode;
import com.qwt.part_time_api.utils.JsonAuthentication;
import com.qwt.part_time_api.utils.JwtUtil;
import com.qwt.part_time_api.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author 君子慎独
 * 成功处理器
 */
@Component
@Slf4j
public class LocalAuthenticationSuccessHandler extends JsonAuthentication implements AuthenticationSuccessHandler {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        log.info("登陆成功");
        // authentication 这个的值就是 UserDetailServiceImpl 登录成功时传递的
        String username = authentication.getName();

        //设置登录状态 防止多设备登录 也是和Token一样时间过期 1 表示登录 如果查不到就证明没登陆
        String s = redisTemplate.opsForValue().get(username + "_QWT-STATE");

        Result result;
        String state = "1";
        String jwt = null;

        // 如果登录
        if (Objects.equals(s, state)) {
            log.info("用户已经登录");
            result = Result.fail(ErrorCode.USER_REPEAT_LOGIN.getErrCode(), ErrorCode.USER_REPEAT_LOGIN.getErrMsg());
        } else {
            log.info("生成token和redis处理");
            //生成jwt Token
            jwt = JwtUtil.generateToken(username);
            // 返回token
            result = Result.success(jwt);
            // 将生成的token存入redis 以备后续刷新token使用  《3天》
            redisTemplate.opsForValue().set("QWT-TOKEN_" + username, JSON.toJSONString(jwt), 259200, TimeUnit.SECONDS);
            // 将登录状态也存入进去 登录状态和token过期时间一致 具体情况再改
            redisTemplate.opsForValue().set(username + "_QWT-STATE", "1", 2, TimeUnit.HOURS);
        }

        //设置响应头
        response.setHeader(JwtUtil.getHeader(), jwt);
        //继承封装的输出JSON格式类，并调用父类方法即可
        this.writeJson(request, response, result);
    }
}


